using System;
using System.Collections.Generic;
using System.Linq;

namespace Core
{
    public class SkillComponent : Entity,IAwake
    {
        private Unit caster;
        private Dictionary<int, ISkill> skills = new Dictionary<int, ISkill>();
        void IAwake.Awake()
        {
            caster = GetParent<Unit>();
        }
        public ISkill AddSkill(int skillId)
        {
            var config = World.GetComponent<ConfigComponent>().GetConfig<SkillConfig>(skillId);
            if (config == null || !config.isVaild)
                return default;

            //var type = World.GetComponent<CodeTypes>().GetType(typeof(SkillAttribute), config.trigger);
            //var skill = Activator.CreateInstance(type) as ISkill;
            var skill = new SkillSystem() as ISkill;
            if (skill == null)
                return default;

            skill.Awake(caster, skillId);
            this.Scene.World.EventSystem.RegisterSystem(skill);
            skills[skillId] = skill;
            return skill;
        }

        public void RemoveSkill(int skillId)
        {
            if(skills.TryGetValue(skillId, out var skill))
            {
                skill.Dispose();
                skills.Remove(skillId);
            }
        }

        public ISkill GetSkill(int skillId)
        {
            skills.TryGetValue(skillId, out var skill);
            return skill;
        }

        public ISkill[] GetSkills()
        {
            return skills.Values.ToArray();
        }

        public void TryCastSkill(SkillCastArgs castArgs)
        {
            if (!skills.TryGetValue(castArgs.skillId, out var skill))
                return;

            var args = new SkillArgs();
            args.direction = castArgs.direction;
            args.position = castArgs.position;

            if (castArgs.targets != null && castArgs.targets.Count > 0)
            {
                var unitComponent = World.GetComponent<UnitComponent>();
                args.targets = new List<Unit>();
                foreach (var unitId in castArgs.targets)
                {
                    var unit = unitComponent.GetUnit(unitId);
                    if (unit == null || unit.IsCanTarget)
                        continue;
                    
                    args.targets.Add(unit);
                }
            }

            if(skill.IsCast())
            {
                skill.Cast(args);
            }
            else
            {
                if (skill.GetCDTime() > 0 || skill.IsInCast())
                    return;

                skill.Start(args);
            }

        }
    }
}